package com.jzhao.gper.spring.v2.aop;

import com.jzhao.gper.spring.v2.aop.aspect.JZAdvice;
import com.jzhao.gper.spring.v2.aop.support.JZAdvisedSupport;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Map;

public class JZJdkDynamicAopProxy implements InvocationHandler {

    private JZAdvisedSupport config;

    public JZJdkDynamicAopProxy(JZAdvisedSupport config) {
        this.config = config;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Map<String,JZAdvice> advices = config.getAdvices(method);
        Object returnValue;
        try{
            invokeAdvice(advices.get("before"));
            returnValue = method.invoke(this.config.getTarget(),args);
            invokeAdvice(advices.get("after"));
        }catch (Exception e){
            invokeAdvice(advices.get("afterThrow"));
            throw e;
        }
        return returnValue;
    }

    private void invokeAdvice(JZAdvice advice) {
        try {
            advice.getAdviceMethod().invoke(advice.getAspect());
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

    public Object getProxy(){
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),this.config.getTargetClass().getInterfaces(),this);
    }


}
